package com.guigu.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guigu.tms.exception.TmsException;
import com.guigu.tms.result.PageResult;
import com.guigu.tms.result.R;
import com.guigu.tms.result.ResultCode;
import com.guigu.user.entity.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigu.user.entity.query.AddressBookQuery;
import com.guigu.user.entity.vo.AddressBookVO;
import com.guigu.user.mapper.AddressBookMapper;
import com.guigu.user.service.*;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 地址簿 服务实现类
 * </p>
 *
 * @author TaoLong
 * @since 2021-11-09
 */
@Service
@CacheConfig(cacheNames = "addressBook")
public class AddressBookServiceImpl extends ServiceImpl<AddressBookMapper, AddressBook> implements AddressBookService {
    @Autowired
    private MemberService memberService;
    @Autowired
    private ProvinceService provinceService;
    @Autowired
    private CityService cityService;
    @Autowired
    private AreaService areaService;

    /**
     * 查询所有地址簿信息
     *
     * @param addressBookQuery 查询对象
     * @param pageSize         查询数量大小
     * @param pageNum          页码
     * @return
     */
    @Cacheable(key = "#addressBookQuery.name+#pageNum+#pageSize")
    @Override
    public PageResult<List<AddressBookVO>> queryByNameOrPhoneOrCompanyName(AddressBookQuery addressBookQuery, Integer pageSize, Integer pageNum) {
        if (pageNum <= 0) {
            pageNum = 1;
        }
        if (pageSize <= 0) {
            pageSize = 5;
        }
        IPage<AddressBook> iPage = new Page<>();
        iPage.setSize(pageSize);
        iPage.setCurrent(pageNum);
        /**
         * 判断是否空,如果为null则直接查询处理
         */
        if (ObjectUtils.isEmpty(addressBookQuery)) {
            IPage<AddressBook> selectPage = this.baseMapper.selectPage(iPage, null);
            List<AddressBookVO> list = getBookVOS(selectPage);
            return new PageResult<>(selectPage.getTotal(), list);
        }

        /**
         * 如果不为空,则按条件查询
         */
        QueryWrapper<AddressBook> queryWrapper = new QueryWrapper<AddressBook>();
        queryWrapper.like("name", addressBookQuery.getName());
        IPage<AddressBook> selectPage = this.baseMapper.selectPage(iPage, queryWrapper);
        /**
         * 先查询出对应的地址信息,将省,市,区县放进对象中
         */
        List<AddressBookVO> list = getBookVOS(selectPage);
        return new PageResult<>(selectPage.getTotal(), list);
    }


    /**
     * 获取AddressBookVO集合
     *
     * @param selectPage
     * @return
     */
    private List<AddressBookVO> getBookVOS(IPage<AddressBook> selectPage) {
        List<AddressBookVO> list = new ArrayList<>();
        for (AddressBook book : selectPage.getRecords()) {
            AddressBookVO addressBookVO = new AddressBookVO();
            if (book.getProvinceId() != null) {
                Province province = provinceService.getById(book.getProvinceId());
                if (ObjectUtils.isNotEmpty(province)) {
                    addressBookVO.setProvince(province.getProvinceName());
                }
            }

            if (book.getCityId() != null) {
                City city = cityService.getById(book.getCityId());
                if (ObjectUtils.isNotEmpty(city)) {
                    addressBookVO.setCity(city.getCityName());
                }

            }
            if (book.getCountyId() != null) {
                Area area = areaService.getById(book.getCountyId());
                if (ObjectUtils.isNotEmpty(area)) {
                    addressBookVO.setCounty(area.getAreaName());
                }
            }
            /**
             * 将之前的属性复制进行
             */
            BeanUtil.copyProperties(book, addressBookVO);
            list.add(addressBookVO);
        }
        return list;
    }

    /**
     * 更改默认地址
     *
     * @param addressBookVO 地址ID
     * @return
     */
    @CacheEvict(allEntries = true)
    @Override
    public R changeTheDefaultAddress(AddressBookVO addressBookVO) {
        if (ObjectUtils.isEmpty(addressBookVO)) {
            throw new TmsException(ResultCode.ERROR_CODE, "参数为(addressBookVO)null");
        }
        if (StringUtils.isBlank(addressBookVO.getUserId())) {
            throw new TmsException(ResultCode.ERROR_CODE, "用户Id为null");
        }
        /**
         * 首先查出来之前设置为默认地址的,如果有设置为不是默认地址
         * 一个用户只能有一个默认地址
         */
        QueryWrapper<AddressBook> queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", addressBookVO.getUserId());
        /**
         * 查询出它的全部地址信息进行判断,找到之前的默认地址,设为false
         */
        List<AddressBook> addressBooks = this.baseMapper.selectList(queryWrapper);
        if (CollUtil.isEmpty(addressBooks)) {
            throw new TmsException(ResultCode.ERROR_CODE, "您还没有地址簿");
        }
        for (AddressBook book : addressBooks) {
            /**
             * 如果之前的地址为true,则修改为false并跳出循环
             */
            if (book.getIsDefault() == true) {
                book.setIsDefault(false);
                this.baseMapper.updateById(book);
                break;
            }
        }
        /**
         * 转换修改默认地址
         */
        AddressBook addressBook = new AddressBook();
        BeanUtil.copyProperties(addressBookVO, addressBook);
        addressBook.setIsDefault(true);
        int i = this.baseMapper.updateById(addressBook);
        return i > 0 ? new R(ResultCode.SUCCESS_CODE, "设置默认地址成功!", true) : new R(ResultCode.ERROR_CODE, "设置默认地址失败!", false);
    }

    /**
     * 根据用户id查询所对应的地址信息
     *
     * @param query
     * @param pageSize
     * @param pageNum
     * @return
     */
    @Override
    @Cacheable(key = "#query.userId+#query.name+#pageNum+#pageSize")
    public R<Page<AddressBookVO>> queryAddressBookBasedOnUserId(AddressBookQuery query, Integer pageSize, Integer pageNum) {
        if (ObjectUtils.isEmpty(query)) {
            throw new TmsException(ResultCode.ERROR_CODE, "参数query为null");
        }
        if (pageSize <= 0)
            pageSize = 5;

        if (pageNum <= 0)
            pageNum = 1;
        if (StringUtils.isBlank(query.getUserId())) {
            throw new TmsException(ResultCode.ERROR_CODE, "参数userId为null");
        }
        /**
         * 检查是否审核过的
         */
        checkAndReview(query.getUserId());
        IPage<AddressBook> iPage = new Page<>();
        /**
         * 放入页码,页数等数据
         */
        iPage.setSize(pageSize);
        iPage.setCurrent(pageNum);
        QueryWrapper<AddressBook> queryWrapper = new QueryWrapper<>();
        /**
         * 查询条件
         */
        queryWrapper.eq("user_id", query.getUserId());
        queryWrapper.like("name", query.getName());
        IPage<AddressBook> selectPage = this.baseMapper.selectPage(iPage, queryWrapper);

        /**
         * 查询的selectPage如果为null,则直接异常
         */
        if (ObjectUtils.isEmpty(selectPage)) {
            throw new TmsException(ResultCode.ERROR_CODE, "您要查询的信息没有");
        }
        /**
         * 将AddressBook集合转为AddressBookVO集合
         */
        List<AddressBookVO> bookVOS = getBookVOS(selectPage);
        Page<AddressBookVO> ipage = new Page<AddressBookVO>();
        /**
         * 将selectPage放入ipage数据中
         */
        ipage.setRecords(bookVOS);
        iPage.setCurrent(selectPage.getCurrent());
        ipage.setSize(selectPage.getSize());
        iPage.setPages(selectPage.getPages());
        iPage.setTotal(selectPage.getTotal());
        return new R<>(ResultCode.SUCCESS_CODE, ipage);
    }


    /**
     * 检验该用户是否通过审核
     *
     * @param id
     */
    @Override
    public void checkAndReview(String id) {
        Member member = memberService.getById(id);
        if (ObjectUtils.isEmpty(member))
            throw new TmsException(ResultCode.ERROR_CODE, "您要查找的信息不存在!");
        if (null == member.getIdCardNoVerify() || member.getIdCardNoVerify() == false)
            throw new TmsException(ResultCode.ERROR_CODE, "该用户审核未通过!");
    }
}
